﻿using System;
using System.Drawing;
using System.Threading;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;

namespace EnhancedSolutions.Admin.BramNuyts.EnhancedSolutions
{
    public partial class AddSolutions : LayoutsPageBase
    {
        private string solutionName, savePath;
        private string resultSessionName = Global.Default.AddSolutions_ResultSessionName;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session[resultSessionName] != null)
            {
                Helper.SetStatus(WspUploadStatus, Session[resultSessionName] as StatusMessage);
            }
        }

        protected void Btn_Ok_Click(object sender, EventArgs e)
        {
            if (WspUpload.HasFile)
            {
                using (SPLongOperation longOperation = new SPLongOperation(this.Page))
                {
                    longOperation.LeadingHTML = "Processing solution";
                    longOperation.TrailingHTML = "Please wait while solution operations are being processed.";
                    solutionName = WspUpload.FileName;
                    savePath = String.Format("{0}{1}", System.IO.Path.GetTempPath(), WspUpload.FileName);
                    try
                    {
                        longOperation.Begin();
                        // Save the file to the temp directory
                        WspUpload.SaveAs(savePath);
                        // Add the solution to the farm solutions, upgrade if checked
                        if (DeploySettingsRadioList.SelectedValue.Equals("Upgrade"))
                        {
                            UpgradeSolution(solutionName, savePath);
                            Session[resultSessionName] = new StatusMessage("Solution successfully upgraded.", Color.DarkGreen);
                        }
                        else
                        {
                            SPSolution oSolution = AddSolution(savePath);
                            // If the quick deploy is checked, show the dialog
                            if (DeploySettingsRadioList.SelectedValue.Equals("Quick Deploy"))
                            {
                                DeploySolution(oSolution);
                                Session[resultSessionName] = new StatusMessage("Solution successfully deployed.", Color.DarkGreen);
                            }
                            else
                            {
                                Session[resultSessionName] = new StatusMessage("Solution successfully added.", Color.DarkGreen);
                            }
                        }
                    }
                    catch (SPException ex)
                    {
                        Session[resultSessionName] = new StatusMessage(ex.Message, Color.Red);
                    }
                    catch (Exception ex)
                    {
                        Session[resultSessionName] = new StatusMessage("The following error occured: " + ex.Message, Color.Red);
                    }
                    finally
                    {
                        // Delete the file from the temp directory
                        System.IO.File.Delete(savePath);
                        longOperation.End(HttpContext.Current.Request.Url.AbsolutePath);
                    }
                }
            }
            else
            {
                Session[resultSessionName] = new StatusMessage("Please provide a solution package.", Color.Red);
            }
        }

        private void DeploySolution(SPSolution oSolution)
        {
            try
            {
                oSolution.Deploy(DateTime.Now, true, false);
                WaitForDeployment(oSolution);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void WaitForDeployment(SPSolution oSolution)
        {
            while (!oSolution.Deployed)
            {
                Thread.Sleep(1000);
            }
        }

        private SPSolution AddSolution(string savePath)
        {
            try
            {
                // Add the solution to the local farm solutions' store
                SPSolution oSolution = SPFarm.Local.Solutions.Add(savePath);
                return oSolution;
            }
            catch (Exception ex)
            {
                throw new SPException(ex.Message);
            }
        }

        private void UpgradeSolution(string _solutionName, string _savePath)
        {
            try
            {
                SPSolution oSolution = SPFarm.Local.Solutions[_solutionName];
                
                if (oSolution == null)
                    throw new InvalidOperationException("The solution has not been found. Make sure it exists in the solution store.");

                oSolution.Upgrade(_savePath);
                WaitForDeployment(oSolution);
            }
            catch (Exception ex)
            {
                throw new SPException(ex.Message);
            }
        }
    }
}
